<template>
	<!-- 已设流程列表 -->
	<div class="app-container">
		<el-main>
			<div v-show="show1">
				<div class="search">
					<el-form ref="defaultSearchForm" size="mini"  :inline="true" :model="defaultSearchForm" class="form-inline">
						<el-form-item label="名称：" prop="name">
							<el-input clearable v-model.trim="defaultSearchForm.name" placeholder="请输入名称" />
						</el-form-item>
						<el-form-item label="类型：" prop="flow_type">
							<el-select filterable v-model="defaultSearchForm.flow_type" clearable placeholder="请选择类型">
								<el-option v-for="item in flow_type_data" :key="item.id" :label="item.name" :value="item.id">{{item.name}}</el-option>
							</el-select>
						</el-form-item>
						<el-form-item label="状态：" prop="status">
							<el-select filterable clearable v-model="defaultSearchForm.status" placeholder="请选择状态">
								<el-option label="启用" :value="1"></el-option>
								<el-option label="禁用" :value="0"></el-option>
							</el-select>
						</el-form-item>
						<el-form-item>
							<el-button type="primary" plain @click="defaultSearchSubmit('defaultSearchForm')">搜索</el-button>
							<el-button type="info" plain @click="defaultSearchReset">重置</el-button>
						</el-form-item>
					</el-form>
				</div>
				<el-row :gutter="20" type="flex" align="center">
					<el-col>
						<el-button type="primary" size="small" @click.native="Addprocess()" v-permission="'flow_add'">新增</el-button>
					</el-col>
				</el-row>
				<el-table stripe ref="defaultTable" size="mini" :data="defaultTableData" v-loading="defaultTabLoading" tooltip-effect="dark"
				 style="width: 100%" border highlight-current-row row-key="id">
					<el-table-column type="index" label="序号" width="50">
						<template slot-scope="scope">
							<span>{{(defaultListParams.page - 1) * defaultListParams.page_size + scope.$index + 1}}</span>
						</template>
					</el-table-column>
					<!-- <el-table-column prop="form_module_id" label="模板id" width="180" /> -->
					<el-table-column prop="name" label="名称" show-overflow-tooltip />
					<el-table-column prop="flow_type_name" label="模板类型" width="150"/>
					<el-table-column prop="status" label="是否启用" align="center" width="80">
						<template slot-scope="scope">
							<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" @change="changeStatus($event,scope.row)" v-permission-disabled="'flow_switch'" />
						</template>
					</el-table-column>
					<el-table-column label="操作" width="250px" align="center">
						<template slot-scope="scope">
							<div class="operation">
								<el-button type="primary" icon="el-icon-edit-outline" size="mini" @click.native="showEdit(scope.row)" v-permission="'flow_edit'">编辑</el-button>
								<el-button type="danger" icon="el-icon-delete" size="mini" @click.native="onDel(scope.row.id)" v-permission="'flow_del'">删除</el-button>
							</div>
						</template>
					</el-table-column>
				</el-table>
				<!-- 分页数据 -->
				<el-pagination @size-change="defaultHandleSizeChange" @current-change="defaultHandleCurrentChange"
				 :current-page.sync="defaultCurrent" :page-sizes="[5, 10, 20, 50, 100]" :page-size="defaultListParams.page_size"
				 layout="total, sizes, prev, pager, next, jumper" :total="defaultTotal"></el-pagination>
			</div>

			<transition name="step-fade">
				<div v-show="stepActive === 1 && show2">
					<div class="margin-tb-sm padding-bottom-sm solids-bottom flex justify-between align-center">
						<div class="text-bold">
							类型与模板
						</div>
						<div>
							<el-button class="margin-left-sm" size="mini" @click="firstStepToPrev">返回</el-button>
							<el-button size="mini" type="primary" @click="firstStepToNext">下一步</el-button>
						</div>
					</div>
					<el-form label-width="80px" ref="cuForm" :rules="cuRules" :model="cuForm">
						<el-form-item label="流程名称" prop="name">
							<el-col :span="8">
								<el-input clearable v-model.trim="cuForm.name" placeholder="请输入流程名称" />
							</el-col>
						</el-form-item>
						<el-form-item label="流程类型">
							<el-radio-group v-model="cuForm.cur_flow_type">
								<el-radio v-for="item in flow_type_data" :key="item.id" :value="item.id" :label="item.id" @change="changeFlowType(item.id)">{{ item.name }}</el-radio>
							</el-radio-group>
						</el-form-item>
						<el-form-item label="使用模板">
							<el-radio-group v-model="cuForm.cur_use_module">
								<el-radio :label="0">不使用</el-radio>
								<el-radio :label="1" disabled>使用</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-form>
					<div v-show="cuForm.cur_use_module==2">
						<!-- todo 待完成 流程模板 选择 -->
						<!-- <div>
						<el-row :gutter="20" class="form-module-row">
							<el-col :span="6" v-for="f in formModule" :key="f.id">
								<el-image :class="[ f.id === formModuleChoose ? 'choosed' : '', 'form-module-box']" :src="(f.module_cover || formModuleDefaultCoverSrc)"
								 fit="scale-down" style="text-align: center;" @click="chooseFormModule(f.id)">
								</el-image>
								<div style="text-align: center">
									<span>{{f.name}}</span>
									<el-link :underline="false" icon="el-icon-zoom-in" @click="showbigpic()"></el-link>
								</div>
							</el-col>
						</el-row>
					</div>
					<div class="block" style="text-align: center;">
						<el-pagination :current-page="currentPage" :page-sizes="[12,24]" :total="totalmodel" layout="total,sizes, prev, pager, next"
						 @size-change="handleSizeChange" @current-change="handleCurrentChange">
						</el-pagination>
					</div> -->
					</div>
				</div>
			</transition>

			<transition name="step-fade">
				<div v-show="stepActive === 2 && show2">
					<div class="margin-tb-sm padding-bottom-sm solids-bottom flex justify-between align-center">
						<div class="text-bold">
							流程配置
						</div>
						<div>
							<el-button class="margin-left-sm" size="mini" @click="toPrevStep">上一步</el-button>
							<el-button class="margin-left-sm" size="mini" @click="finish">查看</el-button>
							<el-button size="mini" type="primary" @click="save">保存流程</el-button>
						</div>
					</div>
					<div style="display: flex;min-height: calc(100vh - 188px)" v-if="easyFlowVisible">
						<div style="width: 120px;border-right: 1px solid #dce3e8;border-top: 1px solid #dce3e8;">
							<node-menu @addNode="addNode" ref="nodeMenu"></node-menu>
						</div>
						<div id="flowContainer" ref="flowContainer" class="container flow-container" v-flowDrag>
							<template v-for="node in data.nodeList">
								<flow-node :id="node.id" :key="node.id" :node="node" :activeNodeId="activeId" @deleteNode="deleteNode"
								 @changeNodeSite="changeNodeSite" @nodeRightMenu="nodeRightMenu" @clickNode="clickNode">
								</flow-node>
							</template>
							<div style="position:absolute;top: 2000px;left: 2000px;color: #FFFFFF;">1</div>
						</div>
					</div>
					<flow-info v-if="flowInfoVisible" ref="flowInfo" :data="data">
					</flow-info>
					<flow-node-form ref="nodeForm" :typeProp="nodeFormType" :nodeProp="nodeFormNode" :lineProp="nodeFormLine"
					 :dataProp="data" :openProp.sync="openDrawer" @setLine="setLine" @setNode="setNode">
					</flow-node-form>
				</div>
			</transition>
		</el-main>

		<el-dialog :visible.sync="isshowbigpic">
			<el-image :src="formModule1" fit="scale-down"></el-image>
		</el-dialog>
	</div>


	<!-- <transition name="step-fade">
					<div v-show="stepActive === 2" class="step-view-inner">
						<div style="display: flex;height: 100%;" v-if="easyFlowVisible">
							<div style="width: 120px;border-right: 1px solid #dce3e8;">
								<node-menu @addNode="addNode" ref="nodeMenu"></node-menu>
							</div>
							<div id="flowContainer" ref="flowContainer" class="container flow-container" v-flowDrag>
								<template v-for="node in data.nodeList">
									<flow-node :id="node.id" :key="node.id" :node="node" :activeNodeId="activeId" @deleteNode="deleteNode"
									 @changeNodeSite="changeNodeSite" @nodeRightMenu="nodeRightMenu" @clickNode="clickNode">
									</flow-node>
								</template>
								<div style="position:absolute;top: 2000px;left: 2000px;color: #FFFFFF;">1</div>
							</div>
						</div>
					</div>
				</transition>
			</div> -->
	<!-- shishi diaglog -->

</template>

<script>
	import draggable from 'vuedraggable'
	import {
		jsPlumb
	} from 'jsplumb'
	import {
		easyFlowMixin
	} from './js/easy_flow_mixin'
	import flowNode from './components/node'
	import nodeMenu from './components/node_menu'
	import FlowInfo from './components/info'
	import FlowNodeForm from './components/node_form'
	import lodash from 'lodash'
	import {
		getAllFormModule
	} from './js/get_all_form_modules.js' // 表单模板数据，此处暂时静态
	import {
		getData
	} from './js/data' //默认流程数据
	import formModuleDefaultCover from '@/assets/images/form_module_default_cover.jpg'
	import formModule1 from '@/assets/images/module1.png'
	import {
		getList,
		getFlowType,
		form_module_search,
		save_process,
		checkStatus,
		changeStatus,
		del
	} from '@/api/system/form_module'
	import store from "@/store"
	import {
		Message
	} from 'element-ui'
	export default {
		data() {
			return {
				//展示控制
				show1: true,
				show2: false,

				// 已设流程列表
				defaultTabLoading: true,
				defaultListParams: {
					page: 1,
					page_size: 10,
					name: null,
					status: null,
					flow_type: null
				},
				defaultTableData: [],
				defaultTotal: null,
				defaultCurrent: 1,

				//流程类型
				flow_type_data: [],
				cuForm: {
					id: null,
					name: null,
					cur_flow_type: 1, // 当前选中的流程类型
					cur_use_module: 0 // 使用模板
				},
				cuRules: {
					name: [{
						required: true,
						message: '请输入流程名称',
						trigger: 'blur'
					}]
				},

				isEdit: false, // 是否为编辑
				flow_json: null, // 流程信息

				defaultSearchForm:{
					name: null,
					flow_type: null,
					status:null
				},

				formModuleNew:{},



				radio: "1",
				//获取节点信息

				editnotchange: null, //编辑时候不能修改模板
				//editdialog: false, //编辑弹框

				// 显示大图
				isshowbigpic: false,
				srcList: [
					'https://fuss10.elemecdn.com/8/27/f01c15bb73e1ef3793e64e6b7bbccjpeg.jpeg',
					'https://fuss10.elemecdn.com/1/8e/aeffeb4de74e2fde4bd74fc7b4486jpeg.jpeg'
				],
				totalmodel: null, //每种类型的model数量
				//用于区分模板类型
				index: 1,
				//搜索项目
				searchForm: {
					name: null
				},
				//传递page和page_size的变化
				listParams: {
					page: 1,
					page_size: 12,
					name: null
				},
				currentPage: 1, // 当前页
				//判断显示界面
				//judge1:true,
				//judge2:true,
				// 表单模板数据
				formModule: {},
				// 表单模板默认缩略图
				formModuleDefaultCoverSrc: formModuleDefaultCover,
				// 表单模板1
				formModule1: formModule1,



				// jsPlumb 实例
				jsPlumb: null,
				// 控制画布销毁
				easyFlowVisible: false,
				// 控制流程数据显示与隐藏
				flowInfoVisible: false,
				// 是否加载完毕标志位
				loadEasyFlowFinish: false,
				// 数据
				data: {},
				// 激活的节点
				activeId: undefined,
				// 当前步骤
				stepActive: 0,
				// 表单手风琴展开
				formCollapseActive: '1',
				// 选中的模板id
				formModuleChoose: 0,

				// 选中的连接线
				nodeFormLine: {},
				// 选中的节点
				nodeFormNode: {},
				// 选中的类型node或者line
				nodeFormType: 'node',
				// 配置项抽屉
				openDrawer: false,
			}
		},
		// 一些基础配置移动该文件中
		mixins: [easyFlowMixin],
		components: {
			draggable,
			flowNode,
			nodeMenu,
			FlowInfo,
			FlowNodeForm
		},
		directives: {
			'flowDrag': {
				bind(el, binding, vnode, oldNode) {
					if (!binding) {
						return
					}
					el.onmousedown = (e) => {
						if (e.button == 2) {
							// 右键不管
							return
						}
						//  鼠标按下，计算当前原始距离可视区的高度
						let disX = e.clientX
						let disY = e.clientY
						el.style.cursor = 'move'

						document.onmousemove = function(e) {
							// 移动时禁止默认事件
							e.preventDefault()
							const left = e.clientX - disX
							disX = e.clientX
							el.scrollLeft += -left

							const top = e.clientY - disY
							disY = e.clientY
							el.scrollTop += -top
						}

						document.onmouseup = function(e) {
							el.style.cursor = 'auto'
							document.onmousemove = null
							document.onmouseup = null
						}
					}
				}
			}
		},
		create() {

		},
		mounted() {
			// 获取已设流程列表
			this.getList()
			//获取流程类型
			this.getType()

			this.initFormModule()

		},
		methods: {
			// 获取已设流程列表
			getList() {
				this.defaultTabLoading = true
				return getList(this.defaultListParams)
					.then(res => {
						let {
							data: {
								records,
								total
							}
						} = res;
						this.defaultTableData = records;
						this.defaultTotal = total;
						this.defaultTabLoading = false;
					})
					.catch(() => {
						this.defaultTabLoading = false
					})
			},
			// 已设流程列表 分页 -pageSize改变
			defaultHandleSizeChange(val) {
				this.defaultListParams.page_size = val
				this.getList()
			},
			// 已设流程列表 分页 -pageNum改变
			defaultHandleCurrentChange(val) {
				this.defaultListParams.page = val
				this.getList()
			},

			//获取流程类型
			getType() {
				return getFlowType()
					.then(res => {
						const {
							data
						} = res
						this.flow_type_data = data
						if (data.length > 0) this.cur_flow_type = data[0].id
					})
			},

			// 设置新流程
			Addprocess() {
				this.stepActive = 1
				this.show1 = false
				this.show2 = true
			},

			//切换流程类型
			changeFlowType(id) {

			},

			firstStepToPrev() {
				this.stepActive = 0
				this.show1 = true
				this.show2 = false
			},

			// 进入流程具体配置
			firstStepToNext() {
				// 表单校验
				this.$refs.cuForm.validate(valid => {
					// ~ 校验通过
					if (valid) {
						// 由于先不使用模板
						// 默认预先插入渠道审核（id：1）和客户审核（id：2）两个模板，直接与对应类型id相同，直接设置
						localStorage.setItem('form_module_id', this.cuForm.cur_flow_type)
						this.toNextStep()
					} else {
						// ~ 不通过
						return false;
					}
				});
			},

			resetData() {
				this.$refs.cuForm.clearValidate()
				this.cuForm = {
					id: null,
					name: null,
					cur_flow_type: 1, // 当前选中的流程类型
					cur_use_module: 0 // 使用模板
				}
				localStorage.removeItem('form_module_id')
				this.easyFlowVisible = false
				this.isEdit = false
			},

			//编辑
			showEdit(row) {
				let {
					id,
					name,
					form_module_id,
					use_module,
					flow_json,
					flow_type
				} = row
				this.editnotchange = 0
				this.stepActive = 1
				this.show1 = false
				this.show2 = true
				this.cuForm = {
					id: id,
					name: name,
					cur_flow_type: flow_type,
					cur_use_module: use_module
				}
				localStorage.setItem('form_module_id', row.form_module_id)
				this.flow_json = JSON.parse(row.flow_json)
				this.easyFlowVisible = false
				this.isEdit = true
			},

			//更改启用状态
			changeStatus(status, row) {
				const flag = +!status
				this.$confirm('确认要' + (status ? '启用' : '禁用') + '?', '提示', {
						confirmButtonText: '确定',
						cancelButtonText: '取消',
						type: 'warning',
						dangerouslyUseHTMLString: true
					})
					.then(() => {
						let {
							id,
							flow_type
						} = row
						if (status == 1) {
							checkStatus(flow_type).then(res => {
								const {
									data
								} = res
								if (''+data === 'true') {
									this.$confirm('同一类型的流程应只存在一个流程属于“启用中”，您确定要将该类型的“启用中”流程替换为该流程吗？', '提示', {
											confirmButtonText: '确定',
											cancelButtonText: '取消',
											type: 'warning',
											dangerouslyUseHTMLString: true
										}).then(() => {
											changeStatus(id, flow_type, status).then(res => {
												this.getList()
											})
										})
										.catch(() => {
											this.getList()
										})
								} else {
									changeStatus(id, flow_type, status)
								}
							})
						} else {
							changeStatus(id, flow_type, status)
						}
					}).catch(() => {
						row.status = flag
					})
			},

			// 删除该流程 todo
			onDel(id = false) {
				this.$confirm('确认要删除?', '提示', {
						confirmButtonText: '确定',
						cancelButtonText: '取消',
						type: 'warning',
						dangerouslyUseHTMLString: true
					})
					.then(() => {
						del(id).then(res => {
							let {
								code,
								date,
								message
							} = res;
							this.getList();
							Message({
								message,
								type: "success",
								duration: 1000
							});
						});
					})
			},

			// 重置搜索表单
			defaultSearchReset() {
				this.$refs.defaultSearchForm.resetFields()
				const params = this.$refs.defaultSearchForm.model
				this.defaultListParams = Object.assign(this.defaultListParams, params)
				this.getList()
			},
			// 搜索
			defaultSearchSubmit(formName) {
				this.$refs[formName].validate(valid => {
					if (valid) {
						const params = this.$refs[formName].model
						this.defaultListParams.page = 1
						this.defaultCurrent = 1
						this.defaultListParams = Object.assign(this.defaultListParams, params)
						this.getList()
					} else {
						console.log('error submit!!')
						return false
					}
				})
			},




			//点击显示大图
			showbigpic() {
				//console.log('suibain')
				this.isshowbigpic = true
			},
			// 重置搜索表单
			searchReset() {
				this.$refs.searchForm.resetFields()
				const params = this.$refs.searchForm.model
				var page = this.listParams.page
				var page_size = this.listParams.page_size
				var name = params.name
				var flow_type = this.index
				this.listParams.name = name
				form_module_search(page, page_size, name, flow_type).then(res => {
					this.formModule = res.data.records
					this.totalmodel = res.data.total
				})
			},
			// 搜索
			searchSubmit(formName) {
				this.$refs[formName].validate(valid => {
					if (valid) {
						const params = this.$refs[formName].model
						var page = 1
						var page_size = this.listParams.page_size
						var name = params.name
						var flow_type = this.index
						this.listParams.name = name
						form_module_search(page, page_size, name, flow_type).then(res => {
							//console.log('res', res)
							this.formModule = res.data.records
							this.totalmodel = res.data.total
						})
					} else {
						console.log('error submit!!')
						return false
					}
				})
			},
			// 分页 -pageSize改变
			handleSizeChange(val) {
				this.listParams.page_size = val
				var page = this.listParams.page
				var page_size = this.listParams.page_size
				var name = this.listParams.name
				var flow_type = this.index
				//console.log(flow_type)
				form_module_search(page, page_size, name, flow_type).then(res => {
					//console.log(res)
					this.formModule = res.data.records
					this.totalmodel = res.data.total
				})

			},
			// 分页 -pageNum改变
			handleCurrentChange(val) {
				this.listParams.page = val
				var page = this.listParams.page
				var page_size = this.listParams.page_size
				var name = this.listParams.name
				var flow_type = this.index
				//console.log(flow_type)
				form_module_search(page, page_size, name, flow_type).then(res => {
					//console.log(res)
					this.formModule = res.data.records
					this.totalmodel = res.data.total
				})
			},

			// 填充表单模板
			// 从服务器拉取模板数据
			initFormModule() {
				form_module_search().then(res => {
					if(res.data){
						res.data.forEach((item) => {
							this.formModuleNew['_'+item.flow_type] = item
						})
					}
				})

			},
			// 表单模板手风琴展开事件
			changeFormCollapse(activeName) {

			},
			// 表单模板选中模板
			chooseFormModule(moduleId) {
				this.formModuleChoose = moduleId
				localStorage.setItem('form_module_id', this.formModuleChoose)
				this.toNextStep()
			},




			// 返回唯一标识
			getUUID() {
				return Math.random().toString(36).substr(3, 10)
			},
			// 初始化jsplumb
			jsPlumbInit() {
				this.jsPlumb.ready(() => {
					// 导入默认配置
					this.jsPlumb.importDefaults(this.jsplumbSetting)
					// 会使整个jsPlumb立即重绘。
					this.jsPlumb.setSuspendDrawing(false, true);
					// 初始化节点
					this.loadEasyFlow()
					// 单点击了连接线, https://www.cnblogs.com/ysx215/p/7615677.html
					this.jsPlumb.bind('click', (conn, originalEvent) => {
						this.activeId = undefined

						let tempConn = {}
						this.data.lineList.forEach((line) => {
							if (line.from == conn.sourceId && line.to == conn.targetId) {
								tempConn = lodash.cloneDeep(line)
								tempConn.data = tempConn.data || []
							}
						})
						this.nodeFormLine = lodash.cloneDeep(tempConn) //深拷贝，保证对象更新，实时回显条件
						this.nodeFormType = 'line'
						this.openDrawer = true
					})
					// 连线
					this.jsPlumb.bind("connection", (evt) => {
						let from = evt.source.id
						let to = evt.target.id
						evt.connection.setLabel('通过')
						if (this.loadEasyFlowFinish) {
							this.data.lineList.push({
								from: from,
								to: to,
								label: '通过'
							})
						}
					})

					// 删除连线回调
					this.jsPlumb.bind("connectionDetached", (evt) => {
						this.deleteLine(evt.sourceId, evt.targetId)
					})

					// 改变线的连接节点
					this.jsPlumb.bind("connectionMoved", (evt) => {
						this.changeLine(evt.originalSourceId, evt.originalTargetId)
					})

					// 连线右击
					this.jsPlumb.bind("contextmenu", (evt, e) => {
						console.log('contextmenu', evt)
						e.preventDefault();
						this.$confirm('确定删除所点击的线吗?', '提示', {
							confirmButtonText: '确定',
							cancelButtonText: '取消',
							type: 'warning'
						}).then(() => {
							this.jsPlumb.deleteConnection(evt)
						}).catch(() => {})
					})

					// 连线
					this.jsPlumb.bind("beforeDrop", (evt) => {
						let from = evt.sourceId
						let to = evt.targetId
						if (from === to) {
							this.$message.error('节点不支持连接自己')
							return false
						}
						if (this.hasLine(from, to)) {
							this.$message.error('该关系已存在,不允许重复创建')
							return false
						}
						/* if (this.hashOppositeLine(from, to)) {
							this.$message.error('不支持两个节点之间连线回环');
							return false
						} */
						this.$message.success('连接成功')
						return true
					})

					// beforeDetach
					this.jsPlumb.bind("beforeDetach", (evt) => {
						console.log('beforeDetach', evt)
					})
					this.jsPlumb.setContainer(this.$refs.flowContainer)
				})
			},
			// 加载流程图
			loadEasyFlow() {
				// 初始化节点
				for (var i = 0; i < this.data.nodeList.length; i++) {
					let node = this.data.nodeList[i]
					// 设置源点，可以拖出线连接其他节点
					if (node.type !== 'end') this.jsPlumb.makeSource(node.id, this.jsplumbSourceOptions)
					// // 设置目标点，其他源点拖出的线可以连接该节点
					if (node.type !== 'start') this.jsPlumb.makeTarget(node.id, this.jsplumbTargetOptions)
					this.jsPlumb.draggable(node.id, {
						containment: 'parent',
						stop: function(el) {
							console.log('停止拖拽', el)
						}
					})
				}
				// 初始化连线
				for (var i = 0; i < this.data.lineList.length; i++) {
					let line = this.data.lineList[i]
					this.jsPlumb.connect({
						source: line.from,
						target: line.to,
						label: line.label ? line.label : ''
					}, this.jsplumbConnectOptions)
				}
				this.$nextTick(function() {
					this.loadEasyFlowFinish = true
				})
			},
			// 配置连接线，由子组件回调
			setLine(from, to, label, data) {
				var conn = this.jsPlumb.getConnections({
					source: from,
					target: to
				})[0]
				if (Array.isArray(data) && data.length === 0) {
					label = '通过'
				}
				conn.setLabel(label)
				this.data.lineList.forEach((line) => {
					if (line.from == from && line.to == to) {
						line.label = label
						line.data = data
					}
				})
			},
			// 配置节点，由子组件回调
			setNode(nodeId, data, extraData) {
				let tempExtraData = lodash.cloneDeep(extraData)
				let temp = this.getNodeObj(nodeId)
				temp.data = data
				temp.name = tempExtraData.name
				temp.nodeType = tempExtraData.nodeType
				temp.nodeSwitch = tempExtraData.nodeSwitch
				temp.nodeCanChooseSwitch = tempExtraData.nodeCanChooseSwitch
				temp.nodeCanChooseValue = tempExtraData.nodeCanChooseValue
				temp.nodeCanAddReadersSwitch = tempExtraData.nodeCanAddReadersSwitch
				temp.nodePrevReadersValue = tempExtraData.nodePrevReadersValue
				temp.nodeAfterReadersValue = tempExtraData.nodeAfterReadersValue
			},
			// 删除线
			deleteLine(from, to) {
				this.data.lineList = this.data.lineList.filter(function(line) {
					if (line.from == from && line.to == to) {
						return false
					}
					return true
				})
			},
			// 改变连线
			changeLine(oldFrom, oldTo) {
				this.deleteLine(oldFrom, oldTo)
			},
			// 改变节点的位置
			changeNodeSite(data) {
				for (var i = 0; i < this.data.nodeList.length; i++) {
					let node = this.data.nodeList[i]
					if (node.id === data.nodeId) {
						node.left = data.left
						node.top = data.top
					}
				}
			},
			// 检查新节点是否是开始和结束节点
			checkNewNodeType(type) {
				if ((type === 'start' || type === 'end') && this.data && this.data.nodeList) {
					for (let i in this.data.nodeList) {
						if (this.data.nodeList[i].type === type) return false
					}
				}
				return true
			},
			/**
			 * 拖拽结束后添加新的节点
			 * @param evt
			 * @param nodeMenu 被添加的节点对象
			 * @param mousePosition 鼠标拖拽结束的坐标
			 */
			addNode(evt, nodeMenu, mousePosition) {
				console.log(evt, nodeMenu, mousePosition)
				if (!this.checkNewNodeType(nodeMenu.type)) {
					this.$message.error("起始/结束节点只允许存在一个")
					return
				}
				var screenX = evt.originalEvent.clientX,
					screenY = evt.originalEvent.clientY
				let flowContainer = this.$refs.flowContainer
				var containerRect = flowContainer.getBoundingClientRect()
				var left = screenX,
					top = screenY
				// 计算是否拖入到容器中
				if (left < containerRect.x || left > containerRect.width + containerRect.x || top < containerRect.y ||
					containerRect.y > containerRect.y + containerRect.height) {
					this.$message.error("请把节点拖入到画布中")
					return
				}
				left = left - containerRect.x + flowContainer.scrollLeft
				top = top - containerRect.y + flowContainer.scrollTop
				// 居中
				left -= 85
				top -= 16
				var nodeId = this.getUUID()
				// 动态生成名字
				var origName = nodeMenu.name
				var nodeName = origName
				var index = 1
				while (index < 10000) {
					var repeat = false
					for (var i = 0; i < this.data.nodeList.length; i++) {
						let node = this.data.nodeList[i]
						if (node.name === nodeName) {
							nodeName = origName + index
							repeat = true
						}
					}
					if (repeat) {
						index++
						continue
					}
					break
				}
				var node = {
					id: nodeId,
					name: nodeName,
					type: nodeMenu.type,
					left: left + 'px',
					top: top + 'px',
					ico: nodeMenu.ico
				}
				/**
				 * 这里可以进行业务判断、是否能够添加该节点
				 */
				this.data.nodeList.push(node)
				this.$nextTick(function() {
					if (node.type !== 'end') this.jsPlumb.makeSource(nodeId, this.jsplumbSourceOptions)
					if (node.type !== 'start') this.jsPlumb.makeTarget(nodeId, this.jsplumbTargetOptions)
					this.jsPlumb.draggable(nodeId, {
						containment: 'parent'
					})
				})
			},
			/**
			 * 删除节点
			 * @param nodeId 被删除节点的ID
			 */
			deleteNode(nodeId) {
				this.$confirm('确定要删除节点' + nodeId + '?', '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning',
					closeOnClickModal: false
				}).then(() => {
					/**
					 * 这里需要进行业务判断，是否可以删除
					 */
					this.data.nodeList = this.data.nodeList.filter(function(node) {
						if (node.id === nodeId) {
							// 伪删除，将节点隐藏，否则会导致位置错位
							// node.show = false
							return false
						}
						return true
					})
					this.$nextTick(function() {
						this.jsPlumb.removeAllEndpoints(nodeId);
					})
				}).catch(() => {})
				return true
			},
			// 点击节点，弹出抽屉
			clickNode(nodeId) {
				let cur = this.getNodeObj(nodeId)
				/* if (cur.type === 'start' || cur.type === 'end') {
					this.$message.error("起始/结束节点不可配置")
				} else {

				} */
				this.activeId = nodeId
				this.nodeFormNode = lodash.cloneDeep(cur) //深拷贝，保证对象更新，实时回显条件
				this.nodeFormType = 'node'
				this.openDrawer = true
			},
			// 根据id找到数据
			getNodeObj(nodeId) {
				let tempNode = {};
				this.data.nodeList.forEach((node) => {
					if ('' + node.id === '' + nodeId) {
						tempNode = node
					}
				})
				return tempNode
			},
			// 是否具有该线
			hasLine(from, to) {
				for (var i = 0; i < this.data.lineList.length; i++) {
					var line = this.data.lineList[i]
					if (line.from === from && line.to === to) {
						return true
					}
				}
				return false
			},
			// 是否含有相反的线
			hashOppositeLine(from, to) {
				return this.hasLine(to, from)
			},
			// 节点右键菜单，暂时未使用
			nodeRightMenu(nodeId, evt) {
				this.menu.show = true
				this.menu.curNodeId = nodeId
				this.menu.left = evt.x + 'px'
				this.menu.top = evt.y + 'px'
			},
			// 弹框显示流程数据信息
			dataInfo() {
				this.flowInfoVisible = true
				this.$nextTick(function() {
					this.$refs.flowInfo.init()
				})
			},
			// 加载流程图
			dataReload(data) {
				this.easyFlowVisible = false
				this.data.nodeList = []
				this.data.lineList = []
				this.$nextTick(() => {
					data = lodash.cloneDeep(data)
					this.easyFlowVisible = true
					this.data = data
					this.$nextTick(() => {
						this.jsPlumb = jsPlumb.getInstance()
						this.$nextTick(() => {
							this.jsPlumbInit()
						})
					})
				})
			},
			// 步骤条下一步
			toNextStep() {
				this.stepActive++
				if (!this.easyFlowVisible && this.stepActive === 2) {
					this.jsPlumb = jsPlumb.getInstance()
					this.$nextTick(() => {
						//读取默认流程数据
						this.dataReload(this.isEdit ? this.flow_json : getData())
					})
				}
			},
			// 步骤条上一步
			toPrevStep() {
				this.stepActive--
			},
			// 完成流程设计
			finish() {
				// 这里暂时弹框显示流程设计数据
				// 保存流程数据
				this.flowInfoVisible = true
				//console.log('data',this.data)
				this.$nextTick(function() {
					this.$refs.flowInfo.init()
				})
			},
			//保存流程设计数据
			save() {
				let postData = {
					name: this.cuForm.name,
					flow_type: this.cuForm.cur_flow_type,
					form_module_id: localStorage.getItem('form_module_id'),
					flow_json: JSON.stringify(this.data),
					data_table: this.formModuleNew['_'+this.cuForm.cur_flow_type].data_table
				}
				if (this.cuForm.id) postData.id = this.cuForm.id;

				save_process(postData)
					.then(res => {
						const {
							code,
							message
						} = res
						if (code == 200) {
							Message({
								message,
								type: 'success',
								duration: 1000
							})
						}
						this.show1 = true
						this.show2 = false

						this.resetData()
						this.getList()
					})
			}
		}
	}
</script>
<style scoped>
	.step-view {
		height: calc(100vh - 170px);
		background-color: #FFFFFF;
		overflow-y: auto;
	}

	.step-view-inner {
		width: 100%;
		height: 100%;
	}

	.own-form-el-collapse {
		border-top: 0;
		padding: 0 20px;
	}

	/* .form-module-row{
		padding: 10px 0;
	} */
	.form-module-box {
		/* width: 100%;
		height: 75px; */
		border: 1px dashed #dce3e8;
		border-radius: 10px;
		box-shadow: 0 0 8px #dce3e8;
		margin: 10px 10px 0 10px;
	}

	.form-module-box.choosed {
		border-style: solid;
		box-shadow: 0 0 8px #7eb2ea;
	}

	.form-module-box:hover {
		cursor: pointer;
		border-style: solid;
		background-color: #f7f7f7;
	}

	#flowContainer {
		position: relative;
		flex: 1;
		overflow: scroll;
	}

	.own-flow-step {
		background-color: #FFFFFF;
		padding: 10px 0;
		border-bottom: 1px solid #dce3e8;
		position: relative;
	}

	.labelClass {
		background-color: white;
		padding: 5px;
		opacity: 0.7;
		border: 1px solid #346789;
		/*border-radius: 10px;*/
		cursor: pointer;
		-webkit-user-select: none;
		-moz-user-select: none;
		-ms-user-select: none;
		user-select: none;
	}

	.flow-tooltar {
		padding-left: 10px;
		box-sizing: border-box;
		height: 42px;
		line-height: 42px;
		z-index: 3;
		-webkit-box-shadow: 0 8px 12px 0 rgba(0, 52, 107, .04);
		box-shadow: 0 8px 12px 0 rgba(0, 52, 107, .04);
		border-bottom: 1px solid #DADCE0;
	}

	/deep/.jtk-overlay {
		font: 12px sans-serif;
		color: black;
		border: 1px solid #c9cbce;
		background-color: #FFFFFF;
		border-radius: 5px;
		padding: 3px 5px;
		word-wrap: break-word;
		word-break: normal;
		max-width: 200px;
		z-index: 2000;
	}

	/deep/.jtk-overlay:hover {
		cursor: pointer;
		background-color: #f7f7f7;
	}

	.next-step {
		position: absolute;
		top: calc(50% - 14px);
		/* right: calc(16.6667% - 110px); */
		right: calc(25% - 110px);
	}

	.save-step {
		position: absolute;
		top: calc(50% - 14px);
		/* right: calc(16.6667% - 110px); */
		right: calc(25% - 200px);
	}

	.prev-step {
		position: absolute;
		top: calc(50% - 14px);
		/* left: calc(16.6667% - 110px); */
		left: calc(25% - 110px);
	}

	.step-fade-enter-active {
		transition: all .5s ease;
	}

	.step-fade-leave-active {
		transition: all 0s ease;
	}

	.step-fade-enter {
		transform: translateX(20px);
		opacity: 0;
	}

	.step-fade-leave-to {
		transform: translateX(-20px);
		opacity: 0;
	}

	#flowContainer {
		border-top: 1px solid #dce3e8;
	}

	.flow-container::-webkit-scrollbar {
		width: 4px;
		height: 4px;

	}

	.flow-container::-webkit-scrollbar-thumb {
		border-radius: 4px;
		background: #E0E3E7;
		height: 20px;

	}

	.flow-container::-webkit-scrollbar-track {
		background-color: transparent;
	}

	.operation button {
		padding: 8px;
	}
</style>

<style lang="scss" scoped>
	.app-container {
		.el-table {
			margin-top: 20px;
		}

		.city-tag {
			margin: 0 3px;
		}
	}
</style>
